#include <iostream>

using namespace std;
//多态
//多态是C++面向对象三大特性之一

//多态分为两类
//静态多态: 函数重载 和 运算符重载属于静态多态，复用函数名
//动态多态: 派生类和虚函数实现运行时多态
//静态多态和动态多态区别：
//静态多态的函数地址早绑定  -  编译阶段确定函数地址
//动态多态的函数地址晚绑定  -  运行阶段确定函数地址
class Animal {
public:
    // 如果没有在speak函数前加virtual，则是地址早绑定，即代码在编译的过程中，确定为animal的speak
    // 在speak函数前加virtual后，则是地址晚绑定，即代码在运行的过程中由创建的对象确定speak
    virtual void speak() {
        cout << "动物在说话" << endl;
    }
};

class Cat : public Animal {
public:
    void speak() {
        cout << "小猫在说话" << endl;
    }
};

class Dog : public Animal {
public:
    void speak() {
        cout << "小狗在说话" << endl;
    }
};

//我们希望传入什么对象，那么就调用什么对象的函数
//如果函数地址在编译阶段就能确定，那么静态联编
//如果函数地址在运行阶段才能确定，就是动态联编
//重写：函数返回值类型  函数名 参数列表 完全一致称为重写
void doSpeak(Animal &animal) {
    animal.speak();
}

//多态满足条件：
//1、有继承关系
//2、子类重写父类中的虚函数
//多态使用：
//父类指针或引用指向子类对象
void test1() {
    Cat cat;
    doSpeak(cat);
    Dog dog;
    doSpeak(dog);
}

int main() {
    test1();
    return 0;
}